package org.ala.tiktools.rocketmq.producer;

import org.ala.tiktools.logs.LoggerFactory;
import org.ala.tiktools.rocketmq.MethodUtils;
import org.ala.tiktools.rocketmq.Namespace;
import org.ala.tiktools.rocketmq.annotations.ProducerMethod;
import org.ala.tiktools.rocketmq.annotations.ProducerService;
import org.ala.tiktools.rocketmq.config.ConfigInfo;
import org.ala.tiktools.rocketmq.producer.queue.IQueueSelecter;
import org.ala.tiktools.rocketmq.producer.transaction.DefaultTransactionListener;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.slf4j.Logger;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.stream.Collectors;


/**
 *  ProducerService 初始化器
 *
 *  @author ala
 *  @date 2024-12-05 11:45
 */
public class RocketMQProducerInitializer {


    static Logger log = LoggerFactory.getLogger("rocketmq", "init");


    static RocketMQProducerInitializer instance;
    private RocketMQProducerInitializer() {}
    public static RocketMQProducerInitializer getInstance() {
        if (instance == null) {
            synchronized (RocketMQProducerInitializer.class) {
                if (instance == null) {
                    instance = new RocketMQProducerInitializer();
                }
            }
        }
        return instance;
    }


    /**
     *  注册ProducerService
     */
    public Map<Method, ProducerExecutor> parse(Class<?> producerServiceClass, ApplicationContext applicationContext) {
        //  取ProducerSerivce注解里的信息
        ProducerService anno = producerServiceClass.getAnnotation(ProducerService.class);

        //  namesrcAddrs地址，group，topic
        String namesrcAddrs;
        if (!anno.namesrvAddrs().equals(Namespace.NULL)) {
            namesrcAddrs = ConfigInfo.INSTANCE.replaceEnv(anno.namesrvAddrs());
        } else {
            namesrcAddrs = ConfigInfo.INSTANCE.getNamesrvAddr();
        }
        String group = ConfigInfo.INSTANCE.replaceEnv(anno.group());
        String topic = ConfigInfo.INSTANCE.replaceEnv(anno.topic());

        //  默认队列数量
        int defaultQueueNum = anno.defaultQueueNum();

        //  扫描所有ProducerMethod注解的方法，每个方法注册一个Producer
        Map<ProducerMethod, Method> methods = MethodUtils.findMethods(producerServiceClass, ProducerMethod.class);

        return methods.entrySet().stream().collect(Collectors.toMap(
                e -> e.getValue(),
                e -> parseMethod(namesrcAddrs, group, topic, defaultQueueNum, e.getKey(), e.getValue(), applicationContext),
                (o,n) -> n));
    }
    protected ProducerExecutor parseMethod(String namesrcAddrs, String group, String topic,
                           int defaultQueueNum,
                           ProducerMethod anno,
                           Method method,
                           ApplicationContext applicationContext) {
        //  group, topic, tag
        if (!anno.group().equals(Namespace.NULL)) {
            group = ConfigInfo.INSTANCE.replaceEnv(anno.group());
        }
        if (!anno.topic().equals(Namespace.NULL)) {
            topic = ConfigInfo.INSTANCE.replaceEnv(anno.topic());
        }
        String tag = ConfigInfo.INSTANCE.replaceEnv(anno.tag());

        //  队列选择器class
        Class<? extends IQueueSelecter> selectorClass = anno.queueSelector().equals(Namespace.NULL_SELECTOR) ? null : anno.queueSelector();
        //  事务监听class
        Class<? extends TransactionListener> transactionClass = anno.transaction().equals(Namespace.NULL_TRANSACTION) ? null : anno.transaction();

        //  默认队列数量
        if (!(anno.defaultQueueNum() == Namespace.INF)) {
            defaultQueueNum = anno.defaultQueueNum();
        }

        ProducerExecutor executor = new ProducerExecutor(
                namesrcAddrs, group, topic, tag,
                defaultQueueNum,
                selectorClass, transactionClass,
                applicationContext);
        return executor;
    }
}
